﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using AppEnvironment.Lib;
using System.Collections;
using AppEnvironment.Web;
using AppEnvironment.Lib.Interfaces;

namespace AppEnvironment
{
    public static class Navigation
    {
        private static Hashtable ReturnParams
        {
            get
            {
                Hashtable returnParams = App.Session["Navigation.ReturnParams"] as Hashtable;
                if (returnParams == null)
                {
                    returnParams = new Hashtable();
                    App.Session["Navigation.ReturnParams"] = returnParams;
                }
                return returnParams;
            }
        }

        public static void Go<T>()
            where T : Presenter
        {
            Go(typeof(T), (object)null);
        }

        public static void Go(NavParam navParams)
        {
            Go(navParams.GetType(), navParams);
        }

        public static void Go(NavParam navParams, NavParam returnParams)
        {
            object view;
            if (GetMap().TryGetValue(navParams.GetType().FullName, out view))
            {
                if (returnParams != null)
                {
                    ReturnParams[GetUrl(navParams)] = returnParams;
                }

                Navigator nav = App.New<Navigator>();
                nav.GoTo(view, navParams);
            }
        }

        private static void Go(Type navType, object navParams)
        {
            object view;
            if (GetMap().TryGetValue(navType.FullName, out view))
            {
                Navigator nav = App.New<Navigator>();
                nav.GoTo(view, navParams);
            }
        }
        
        
        public static string GetUrl<T>()
            where T : Presenter
        {
            return GetUrl(typeof(T), null, null, null);
        }

        public static string GetUrl(NavParam navParams)
        {
            return GetUrl(navParams.GetType(), navParams, null, null);
        }

        public static string GetUrl(NavParam navParams, NavParam returnParams)
        {
            return GetUrl(navParams.GetType(), (object)navParams, GetUrl(navParams), returnParams);
        }

        private static string GetUrl(Type navType, object destParams, string destViewKey, NavParam returnParams)
        {
            object view;
            if (GetMap().TryGetValue(navType.FullName, out view))
            {
                if (returnParams != null)
                {
                    ReturnParams[destViewKey] = returnParams;    
                }

                Navigator nav = App.New<Navigator>();
                return nav.GetUrl(view, destParams, false);
            }
            return null;
        }



        public static bool CanReturn(string viewKey, out string name, out string link)
        {
            name = null;
            link = null;

            NavParam returnParams = ReturnParams[viewKey] as NavParam;
            if (returnParams != null)
            {
                object view;
                if (GetMap().TryGetValue(returnParams.GetType().FullName, out view))
                {   

                    Navigator nav = App.New<Navigator>();
                    link = nav.GetUrl(view, returnParams, true);
                    name = returnParams.GetName();
                    return true;
                }
            }

            return false;
        }

        public static bool IsReturning()
        {
            Navigator nav = App.New<Navigator>();
            return nav.IsReturning();
        }

        public static void RegisterNavigation<T>(object view)
        {
            GetMap(App.InstanceInternal.GetApplication())[typeof(T).FullName] = view;
        }

        private static SortedList<string, object> GetMap()
        {
            return GetMap(App.Application);
        }

        private static SortedList<string, object> GetMap(IStateHolder application)
        {
            object objValue = application["Navigator_Map"];
            SortedList<string, object> result = objValue as SortedList<string, object>;
            if (result == null)
            {
                result = new SortedList<string, object>();
                application["Navigator_Map"] = result;

            }
            return result;
        }
    }
}
